package com.bby.disk.manager.upload;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.MD5;
import com.bby.common.config.GlobalSettings;
import com.bby.common.exception.BBYException;
import com.bby.common.utils.BBYUtils;
import com.bby.common.utils.StatusCode;
import com.bby.disk.manager.virtual.VirtualManager;
import com.bby.disk.manager.virtual.VirtualObjNotFoundException;
import com.bby.disk.util.BBYFileSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class OfflineThreadTask extends Thread{
    OfflineTask task;
    long finishedSize=0;
    URL url;
    Logger logger = LoggerFactory.getLogger(this.getClass());
    File tempFile;
    private boolean cancel = false;
    public OfflineThreadTask(OfflineTask task) throws BBYException {
        try {
            this.url=new URL(task.getUrl());
        } catch (MalformedURLException e) {
            throw new BBYException(StatusCode.INPUT_ERROR,"地址错误！");
        }
        this.task=task;
    }

    public boolean isFinished(){
        return finishedSize == task.file.getSize();
    }
    @Override
    public void run() {
        downloadStart();
        downLoadFromUrl();
        downloadStop();
    }

    /**
     * http地址下载文件
     */
    private void downLoadFromUrl() {
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) url.openConnection();
        } catch (IOException e) {
            return;
        }
        //设置超时间为10秒
        conn.setConnectTimeout(10 * 1000);
        //防止屏蔽程序抓取而返回403错误
//        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//        conn.setRequestProperty("lfwywxqyh_token",toekn);
        dealFileName(conn);
        dealFileSize(conn);
        if (BBYUtils.isEmpty(task.file.getName())||task.file.getSize()<0){
            conn.disconnect();
            return;
        }
        downloadRunning();
        //文件保存位置
        tempFile = new File(GlobalSettings.TEMP_FILES_DIR + File.separator + task.id);
//        //得到输入流
        try (InputStream inputStream = conn.getInputStream();
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tempFile))) {
            byte[] buf = new byte[4096];
            int len;
            while ((len=inputStream.read(buf))>-1){
                if (cancel){
                    tempFile.delete();
                    return;
                }
                bos.write(buf,0,len);
                finishedSize+=len;
                if (finishedSize%409600==0){
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                    }
                    System.out.println(finishedSize+"/"+task.file.getSize());
                }
            }
        } catch (IOException ignored) {}
        conn.disconnect();
        logger.info("---------- 文件地址：" + url + " 下载成功");
    }

    private void downloadRunning(){
        task.status="running";
        logger.debug("Running: {}",task);
        OfflineThreadManager.saveTask(task);
    }
    private void downloadStart(){
        task.status="prepare";
        task.file.setSize(-1);
        finishedSize=0L;
        logger.debug("Start: {}",task);
        OfflineThreadManager.saveTask(task);
    }

    private void downloadStop(){
        if (cancel){// 手动取消不保存结果
            return;
        }
        if (isFinished()&&tempFile!=null&&tempFile.exists()){
            task.status = "success";
            try {
                MD5 md5 = new MD5();
                task.file.setMd5(md5.digestHex(tempFile));
                VirtualManager.create(task.file);
                BBYFileSystem.add(tempFile,task.file.getMd5());
                OfflineThreadManager.futureMap.remove(task.getId());
                task.status = "success";
            } catch (BBYException e) {
                task.status= "fail";
                tempFile.delete();
            }
        }else {
            task.status= "fail";
        }
        logger.debug("Stop: {}",task);
        OfflineThreadManager.saveTask(task);
    }

    public void stopRun() {
        downloadStop();
        cancel=true;
        logger.debug("stopRun: {}",task);
    }


    private void dealFileSize(HttpURLConnection conn) {
        String header = conn
                .getHeaderField("Content-Length");
        if (!Validator.isNumber(header)){
            return;
        }
        System.out.println("header="+header);
        long size = Long.parseLong(header);
        try {
            VirtualManager.storageUseCheck(task.file.getOwner(),size);
        } catch (BBYException e) {
            downloadStop();
            stopRun();
        }
        task.file.setSize(size);
    }
    private void dealFileName(HttpURLConnection conn){
        String disposition = conn
                .getHeaderField("Content-Disposition");
        if (ObjectUtil.isEmpty(disposition)){
            return ;
        }
        String name;
        try {
            for (String item : disposition.split(";")) {
                if (item.startsWith("filename")){
                    name = item.replace("filename=","")
                            .replaceAll("[\"']","");
                    task.file.setName(URLDecoder.decode(name, StandardCharsets.UTF_8.name()));
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {}
    }
}
